/*
    SUSAN® - Sole of Unix Save ANything

   Copyright (C) 2002-2010 Hechzh Property
   

   
*/
/*
 * Kern Sibbald, July 2002
 */
/**
 * @file
 * Bootstrap Record header file
 *
 * BootStrapRecord (bootstrap record) handling routines split from ua_restore.c
 * July 2003 Bootstrap send handling routines split from restore.c July 2012
 */

#ifndef BAREOS_DIRD_BSR_H_
#define BAREOS_DIRD_BSR_H_

#include "dird/ua.h"

struct VolumeParameters;

namespace directordaemon {

/**
 * FileIndex entry in restore bootstrap record
 */
class RestoreBootstrapRecordFileIndex {
 private:
  std::vector<int32_t> fileIds_;
  bool allFiles_ = false;
  bool sorted_ = false;
  void Sort();

 public:
  void Add(int32_t findex);
  void AddAll();
  std::vector<std::pair<int32_t, int32_t>> GetRanges();
  bool Empty() const { return !allFiles_ && fileIds_.empty(); }
};

/**
 * Restore bootstrap record -- not the real one, but useful here
 *  The restore bsr is a chain of BootStrapRecord records (linked by next).
 *  Each BootStrapRecord represents a single JobId, and within it, it
 *    contains a linked list of file indexes for that JobId.
 *    The AddVolumeInformationToBsr() routine, will then add all the volumes
 *    on which the Job is stored to the BootStrapRecord.
 */
struct RestoreBootstrapRecord {
  std::unique_ptr<RestoreBootstrapRecord> next; /**< next JobId */
  JobId_t JobId = 0;                            /**< JobId this bsr */
  uint32_t VolSessionId = 0;
  uint32_t VolSessionTime = 0;
  int VolCount = 0;                      /**< Volume parameter count */
  VolumeParameters* VolParams = nullptr; /**< Volume, start/end file/blocks */
  std::unique_ptr<RestoreBootstrapRecordFileIndex>
      fi;                    /**< File indexes this JobId */
  char* fileregex = nullptr; /**< Only restore files matching regex */

  RestoreBootstrapRecord();
  RestoreBootstrapRecord(JobId_t t_JobId);
  virtual ~RestoreBootstrapRecord();
  RestoreBootstrapRecord(const RestoreBootstrapRecord&) = delete;
  RestoreBootstrapRecord& operator=(const RestoreBootstrapRecord&) = delete;
  RestoreBootstrapRecord(RestoreBootstrapRecord&&) = delete;
  RestoreBootstrapRecord& operator=(RestoreBootstrapRecord&&) = delete;
};

class UaContext;

/**
 * Open bootstrap file.
 */
struct bootstrap_info {
  FILE* bs;
  UaContext* ua;
  char storage[MAX_NAME_LENGTH + 1];
};

bool AddVolumeInformationToBsr(UaContext* ua, RestoreBootstrapRecord* bsr);
uint32_t WriteBsrFile(UaContext* ua, RestoreContext& rx);
void DisplayBsrInfo(UaContext* ua, RestoreContext& rx);
uint32_t WriteBsr(UaContext* ua, RestoreContext& rx, std::string& buffer);
void AddFindex(RestoreBootstrapRecord* bsr, uint32_t JobId, int32_t findex);
void AddFindexAll(RestoreBootstrapRecord* bsr, uint32_t JobId);
RestoreBootstrapRecordFileIndex* new_findex();
void MakeUniqueRestoreFilename(UaContext* ua, POOLMEM*& fname);
void PrintBsr(UaContext* ua, RestoreContext& rx);
bool OpenBootstrapFile(JobControlRecord* jcr, bootstrap_info& info);
bool SendBootstrapFile(JobControlRecord* jcr,
                       BareosSocket* sock,
                       bootstrap_info& info);
void CloseBootstrapFile(bootstrap_info& info);
uint32_t write_findex(RestoreBootstrapRecordFileIndex* fi,
                      int32_t FirstIndex,
                      int32_t LastIndex,
                      std::string& buffer);

} /* namespace directordaemon */
#endif  // BAREOS_DIRD_BSR_H_
